package seckill

import (
	"context"
	"fmt"
	"gin_miaosa/zhiliao_web/rabbitmq"
	"gin_miaosa/zhiliao_web/redis_lib"
	"gin_miaosa/zhiliao_web/utils"
	"net/http"

	zhiliao_seckill_srv "gin_miaosa/zhiliao_seckill_srv/seckill_proto/seckill_seckill"

	"github.com/garyburd/redigo/redis"
	"github.com/gin-gonic/gin"
	"github.com/go-micro/plugins/v4/client/grpc"
	"go-micro.dev/v4"
)

// todo  init 函数 初始化mq以及redis
func SecKill_rpc(ctx *gin.Context)  {
	id := ctx.PostForm("id")
	// front_user_email,exist := ctx.Get("front_user_name")
	front_user_email:="1500876109@qq.com"
	exist:=true
	fmt.Println("==========SecKill===========",id,front_user_email)
	// grpc 通信
	service := micro.NewService(
		micro.Client(grpc.NewClient()),
	)
	service.Init()
	client := zhiliao_seckill_srv.NewSecKillService("zhiliao.seckill.srv.zhiliao_seckill_srv",service.Client())
	rep, _ := client.FrontSecKill(context.TODO(),&zhiliao_seckill_srv.SecKillRequest{
				Id:utils.StrToInt(id),
				// FrontUserEmail:front_user_email.(string),
				FrontUserEmail:front_user_email,
	})
		ctx.JSON(http.StatusOK,gin.H{
			"code":rep.Code,
			"msg":rep.Msg,
		})

	if !exist {
		ctx.JSON(http.StatusOK,gin.H{
			"code":500,
			"msg":"token有问题",
		})
	}
}


// 秒杀接口
func SecKill(ctx *gin.Context)  {
	id := ctx.PostForm("id")
	// front_user_email,exist := ctx.Get("front_user_name")
	front_user_email:="1500876109@qq.com"
	fmt.Println("==========SecKill===========",id,front_user_email)
	// grpc 通信
	// service := micro.NewService(
	// 	micro.Client(grpc.NewClient()),
	// )
	// service.Init()
	// client := zhiliao_seckill_srv.NewSecKillService("zhiliao.seckill.srv.zhiliao_seckill_srv",service.Client())
	// rep, _ := client.FrontSecKill(context.TODO(),&zhiliao_seckill_srv.SecKillRequest{
	// 			Id:utils.StrToInt(id),
	// 			// FrontUserEmail:front_user_email.(string),
	// 			FrontUserEmail:front_user_email,
	// })
	// 	ctx.JSON(http.StatusOK,gin.H{
	// 		"code":rep.Code,
	// 		"msg":rep.Msg,
	// 	})

	// if !exist {
	// 	ctx.JSON(http.StatusOK,gin.H{
	// 		"code":500,
	// 		"msg":"token有问题",
	// 	})
	// }

	// redis +lua版本
//测试 在每秒并发量为50的情况下 完全没问题
	duplicate_uniqueKey := fmt.Sprintf("%s:%s_duplicate", front_user_email, id)
	script := `
			local unique_key = ARGV[1]
			local isDuplicate = redis.call("EXISTS", unique_key)
			if isDuplicate == 1 then
				return 1
			else
				redis.call("SET", unique_key, 1)
				redis.call("EXPIRE", unique_key, 3) 
				return 0
			end
		`
	is_duplicate, err := redis.Int(redis_lib.Conn.Do("EVAL", script, 0, duplicate_uniqueKey))
	if err != nil {
		fmt.Println("Redis Lua script execution error:", err)
		redis_lib.Reconnet()
		return
	}
	if is_duplicate == 1 {
		// 重复提交，返回错误或做相应处理
		fmt.Println("重复提交!!!!",duplicate_uniqueKey)
		ctx.JSON(http.StatusOK,gin.H{
			"code":500,
			"msg":"重复提交!!",
		})
		return
	}


	// redis 没有lua版本
	// 使用SETNX命令来设置键的值，只有在键不存在时才设置成功
	// isDuplicate, err := redis.Int(redis_lib.Conn.Do("EXISTS", duplicate_uniqueKey))
	// if err != nil {
	// 	fmt.Println("Redis error:", err)
	// 	redis_lib.Reconnet()
	// 	return
	// }
	// if isDuplicate == 1 {
	// 	// 处理重复提交的逻辑
	// 	fmt.Println("重复提交!!!!", duplicate_uniqueKey)
	// 	ctx.JSON(http.StatusOK, gin.H{
	// 		"code": 500,
	// 		"msg":  "重复提交!!",
	// 	})
	// 	return
	// } else {
	// 	// 设置键的值和过期时间
	// 	_, err := redis_lib.Conn.Do("SET", duplicate_uniqueKey, 1)
	// 	if err != nil {
	// 		fmt.Println("Redis error:", err)
	// 		redis_lib.Reconnet()
	// 		return
	// 	}
	// 	_, err = redis_lib.Conn.Do("EXPIRE", duplicate_uniqueKey, 3)
	// 	if err != nil {
	// 		fmt.Println("Redis error:", err)
	// 		redis_lib.Reconnet()
	// 		return
	// 	}
	// }


	qe := rabbitmq.QueueAndExchange{
		QueueName:"zhiliao_web.order_queue",
		ExchangeName:"zhiliao_web.order_exchange",
		ExchangeType:"direct",
		RoutingKey:"zhiliao_web.order",

	}
	mq := rabbitmq.NewRabbitMq(qe)

	mq.ConnMq()
	mq.OpenChan()

	defer func() {
		mq.CloseMq()
	}()
	defer func() {
		mq.CloseChan()
	}()

	order_map := map[string]interface{}{
		"uemail":front_user_email,
		"pid":id,
	}

	mq.PublishMsg(utils.MapToStr(order_map))

	ctx.JSON(http.StatusOK,gin.H{
		"code":200,
		"msg":"下单中，请稍后",
	})
}


// 通过redis 获取下单结果
func GetSeckillResult(ctx *gin.Context)  {
	// uemail,exist := ctx.Get("front_user_name")
	uemail:= "1500876109@qq.com"
	id := ctx.PostForm("id")
	exist:=true
	fmt.Println("======GetSeckillResult========")
	uniqueKey := fmt.Sprintf("%s:%s", uemail, id)
	fmt.Println("uniqueKey",uniqueKey)

	if exist {
		conn,err := redis.Dial("tcp","127.0.0.1:6379")
		if err != nil {
				fmt.Println("连接出错")
			}
		// uemail="email30@example.com"
		ret,err_r := redis.String(conn.Do("GET",uniqueKey))
		// ret,err_r := redis.String(conn.Do("get","email24@example.com"))
		if err_r == nil {
			ret_map := utils.StrToMap(ret)
			fmt.Println(ret_map)
			ctx.JSON(http.StatusOK,gin.H{ // 说明从redis里面获取到了数据，
				"code":200,
				"msg":ret_map["msg"],
			})
			return
		}
		ctx.JSON(http.StatusOK,gin.H{
			"code":500,
		})
		return
	}
}

// 通过redis 获取下单结果
func Pay(ctx *gin.Context)  {
	// uemail,exist := ctx.Get("front_user_name")
	uemail:= "1500876109@qq.com"
	id := ctx.PostForm("id")
	fmt.Println("======Pay========")
	// grpc 通信
	service := micro.NewService(
		micro.Client(grpc.NewClient()),
	)
	service.Init()
	client := zhiliao_seckill_srv.NewSecKillService("zhiliao.seckill.srv.zhiliao_seckill_srv",service.Client())
	rep, _ := client.Pay(context.TODO(),&zhiliao_seckill_srv.PayRequest{
				Id:utils.StrToInt(id),
				// FrontUserEmail:front_user_email.(string),
				FrontUserEmail:uemail,
	})
	ctx.JSON(http.StatusOK,gin.H{
		"code":rep.Code,
		"msg":rep.Msg,
	})

}
